if (window.cvm === undefined) {
    cvm = {};
}

(function (cvm) {

    cvm.Prototype = {
            __name__: "Prototype",
            __init__: function (spec) {
                if (spec) {
                    for (var prop in spec) {
                        if (spec.hasOwnProperty(prop)) {
                            this[prop] = spec[prop];
                        }
                    }
                }
                return this;
            },
            specialise: function (spec) {
                var name = spec && spec.__name__ || this.__name__;
                var F;
                eval("F = function " + name + " () {};");
                F.prototype = this;
                var obj = new F();
                if (!obj.hasOwnProperty("__proto__")) {
                    obj.__proto__ = this;
                }
                if (spec) {
                    for (var prop in spec) {
                        if (spec.hasOwnProperty(prop)) {
                            // Comment the following in order to be compatible with IE8
                            // This means no more descriptors :(
                            /*var desc = Object.getOwnPropertyDescriptor(spec, prop);
		    var g = desc.get;
		    var s = desc.set;
		    if ( g || s ) {
			var def = {};
			if ( g )
			    def.get = g;
			if ( s )
			    def.set = s;
			Object.defineProperty(obj, prop, def);
		    } else {*/
                            obj[prop] = spec[prop];
                            //}
                        }
                    }
                }
                return obj;
            },
            instanciate: function () {
                var obj = this.specialise();
                obj.__init__.apply(obj, arguments);
                return obj;
            },
            bind: function (prop) {
                return this[prop].bind(this);
            },
            addMixin: function (mixin) {
                for (var prop in mixin) {
                    if (mixin.hasOwnProperty(prop)) {
                        if (this[prop]) {
                            throw "object has property '" + prop + "' already"; 
                        }
                        this[prop] = mixin[prop];
                    }
                }
                return this;
            }
    };

})(cvm);